package com.jyxd.web.task.ZAutoAdviceTask;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jyxd.web.data.basic.MedOrderExec;
import com.jyxd.web.data.basic.NurseRecordForm;
import com.jyxd.web.data.zauto.ZAutoAdviceLogEntity;
import com.jyxd.web.data.zauto.ZAutoAdviceTaskEntity;
import com.jyxd.web.service.assessment.basic.MedOrderExecService;
import com.jyxd.web.service.assessment.basic.NurseRecordFormService;
import com.jyxd.web.service.zauto.ZAutoAdviceLogService;
import com.jyxd.web.service.zauto.ZAutoAdviceTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import static com.jyxd.web.util.UUIDUtil.getUUID;

@Slf4j
@Component
public class ZAutoAdviceTask {

    // 定义日期格式为 "yyyy-MM-dd HH:mm"
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    @Resource
    private ZAutoAdviceTaskService zAutoAdviceTaskService;

    @Resource
    private ZAutoAdviceLogService zAutoAdviceLogService;

    @Resource
    private NurseRecordFormService nurseRecordFormService;

    @Resource
    private MedOrderExecService medOrderExecService;

    /**
     * 每分钟查询需要执行的医嘱
     */
    @Scheduled(cron = "0 * * * * ? ")
    public void autoAdviceTask() {
        log.info("自动医嘱任务开始执行");
        LambdaQueryWrapper<ZAutoAdviceTaskEntity> zAutoAdviceTaskEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        zAutoAdviceTaskEntityLambdaQueryWrapper.eq(ZAutoAdviceTaskEntity::getAutoStatus, 1);
        zAutoAdviceTaskEntityLambdaQueryWrapper.eq(ZAutoAdviceTaskEntity::getDisabled, 1);
        List<ZAutoAdviceTaskEntity> list = zAutoAdviceTaskService.list(zAutoAdviceTaskEntityLambdaQueryWrapper);
        for (ZAutoAdviceTaskEntity zAutoAdviceTaskEntity : list) {
            //TODO 执行医嘱
            log.info("执行医嘱");
            if (zAutoAdviceTaskEntity.getBeginTime() == null || zAutoAdviceTaskEntity.getBeginTime().isEmpty()) {
                continue;
            }
            String adviceIdJson = zAutoAdviceTaskEntity.getAdviceIdJson();
            Integer frequency = zAutoAdviceTaskEntity.getFrequency();//执行频率
            Integer frequencyUnit = zAutoAdviceTaskEntity.getFrequencyUnit();//频率单位 0-小时 1-天 2-月

            List<String> adviceIdList = JSONArray.parseArray(adviceIdJson, String.class);
            //执行次数
            Integer executeNums = zAutoAdviceTaskEntity.getExecuteNums();
            ZAutoAdviceLogEntity zAutoAdviceLogEntity = new ZAutoAdviceLogEntity();
            //计划类型
            Integer adviceType = zAutoAdviceTaskEntity.getAdviceType();
            if(adviceType == 0){
                //临时医嘱
                log.info("临时医嘱");
                zAutoAdviceTaskEntity.setExecuteNums(executeNums - 1);
                if (executeNums - 1 == 0){
                    zAutoAdviceTaskEntity.setDisabled(2);
                }
            } else if (adviceType == 1) {
                //长期医嘱
                log.info("长期医嘱");
            }
            if(zAutoAdviceTaskEntity.getLastExecuteTime() == null || zAutoAdviceTaskEntity.getLastExecuteTime().isEmpty()){
                log.info("没有最后执行时间，是第一次执行医嘱");
                if (isTimeToExecute(zAutoAdviceTaskEntity.getBeginTime(), 0, frequencyUnit)) {
                    log.info("执行医嘱: {}", adviceIdList);
                    Date date = new Date();
                    zAutoAdviceTaskEntity.setLastExecuteTime(dateFormat.format(date));
                    log.info("更新:{} ,执行时间: {}", zAutoAdviceTaskEntity.getId() , dateFormat.format(date));
                    zAutoAdviceTaskService.updateById(zAutoAdviceTaskEntity);
                    //添加日志
                    for (String adviceId : adviceIdList) {

                        zAutoAdviceLogEntity.setAdviceId(adviceId);
                        zAutoAdviceLogEntity.setAutoTaskId(zAutoAdviceTaskEntity.getId());
                        zAutoAdviceLogEntity.setStatus(0);
                        zAutoAdviceLogEntity.setRule("");
                        zAutoAdviceLogEntity.setResult("");
                        zAutoAdviceLogEntity.setExecuteTime(LocalDateTime.now());
                        zAutoAdviceLogService.save(zAutoAdviceLogEntity);

                        NurseRecordForm nurseRecordForm = new NurseRecordForm();
                        MedOrderExec medOrderExec = medOrderExecService.queryData(adviceId);
                        int drugType = medOrderExec.getDrugType();
                        if (drugType == 0) {
                            //非药嘱
                            nurseRecordForm.setNurseMeasure(medOrderExec.getOrderName());
                        }else if(drugType == 1){
                            //药嘱
                            nurseRecordForm.setMedicineContent(medOrderExec.getOrderName());
                        }
                        nurseRecordForm.setId(getUUID());
                        nurseRecordForm.setPatientId(zAutoAdviceTaskEntity.getPatientId());
                        nurseRecordForm.setDataTime(new Date());
                        nurseRecordForm.setDataSource(2);
                        nurseRecordFormService.insert(nurseRecordForm);
                    }
                }
            }else {
                log.info("有上次执行时间，不是第一次执行医嘱");
                if (isTimeToExecute(zAutoAdviceTaskEntity.getLastExecuteTime(), frequency, frequencyUnit)) {
                    log.info("执行医嘱: {}", adviceIdList);
                    Date date = new Date();
                    zAutoAdviceTaskEntity.setLastExecuteTime(dateFormat.format(date));
                    log.info("更新:{} ,执行时间: {}", zAutoAdviceTaskEntity.getId() , dateFormat.format(date));
                    zAutoAdviceTaskService.updateById(zAutoAdviceTaskEntity);
                    //添加日志
                    for (String adviceId : adviceIdList) {

                        zAutoAdviceLogEntity.setAdviceId(adviceId);
                        zAutoAdviceLogEntity.setAutoTaskId(zAutoAdviceTaskEntity.getId());
                        zAutoAdviceLogEntity.setStatus(0);
                        zAutoAdviceLogEntity.setRule("");
                        zAutoAdviceLogEntity.setResult("");
                        zAutoAdviceLogEntity.setExecuteTime(LocalDateTime.now());
                        zAutoAdviceLogService.save(zAutoAdviceLogEntity);

                        NurseRecordForm nurseRecordForm = new NurseRecordForm();
                        MedOrderExec medOrderExec = medOrderExecService.queryData(adviceId);
                        int drugType = medOrderExec.getDrugType();
                        if (drugType == 0) {
                            //非药嘱
                            nurseRecordForm.setNurseMeasure(medOrderExec.getOrderName());
                        }else if(drugType == 1){
                            //药嘱
                            nurseRecordForm.setMedicineContent(medOrderExec.getOrderName());
                        }
                        nurseRecordForm.setId(getUUID());
                        nurseRecordForm.setPatientId(zAutoAdviceTaskEntity.getPatientId());
                        nurseRecordForm.setDataTime(new Date());
                        nurseRecordForm.setDataSource(2);
                        nurseRecordFormService.insert(nurseRecordForm);
                    }
                } else {
                    log.info("未到执行时间");
                }
            }
        }
    }


    /**
     * 判断是否达到任务的执行时间
     *
     * @param begin         开始时间
     * @param frequency     执行频率
     * @param frequencyUnit 频率单位
     * @return
     */
    public static boolean isTimeToExecute(String begin, Integer frequency, Integer frequencyUnit) {
        try {
            // 解析开始时间字符串为 Date 对象
            Date beginTime = dateFormat.parse(begin);

            // 获取当前时间
            Date currentTime = new Date();

            // 计算下一次执行时间
            Date nextExecutionTime = calculateNextExecutionTime(beginTime, frequency, frequencyUnit);
            System.out.println(nextExecutionTime);
            // 判断当前时间是否达到或超过下一次执行时间
            return currentTime.after(nextExecutionTime) || currentTime.equals(nextExecutionTime);
        } catch (ParseException e) {
            // 如果解析日期格式失败，打印堆栈跟踪并返回 false
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据开始时间、频率和频率单位计算下一次执行时间
     *
     * @param beginTime     任务的开始时间
     * @param frequency     任务的执行频率
     * @param frequencyUnit 任务的频率单位（0-小时，1-天，2-月）
     * @return 下一次执行时间的 Date 对象
     */
    private static Date calculateNextExecutionTime(Date beginTime, Integer frequency, Integer frequencyUnit) {
        // 创建一个 Calendar 实例并设置时间为开始时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(beginTime);

        // 根据频率单位添加相应的频率到日历中
        switch (frequencyUnit) {
            case 0: // 小时
                calendar.add(Calendar.HOUR_OF_DAY, frequency);
                break;
            case 1: // 天
                calendar.add(Calendar.DAY_OF_MONTH, frequency);
                break;
            case 2: // 月
                calendar.add(Calendar.MONTH, frequency);
                break;
            default:
                // 如果频率单位无效，抛出 IllegalArgumentException
                throw new IllegalArgumentException("Invalid frequency unit");
        }

        // 返回计算后的下一次执行时间
        return calendar.getTime();
    }

    public static void main(String[] args) {
        String beginTime = "2024-12-29 23:04/";
        Integer frequency = 0;//执行频率
        Integer frequencyUnit = 1;//频率单位 0-小时 1-天 2-月
        boolean timeToExecute = isTimeToExecute(beginTime, frequency, frequencyUnit);
        System.out.println(timeToExecute);
    }
}
